In [1]:
import os
import pickle
import numpy as np
import pandas as pd
import plotly.express as px
import matplotlib.pyplot as plt
from collections import Counter
import sys
package_paths = ['visualisations']
for pth in package_paths:
    sys.path.append(pth)
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
In [2]:
from initialize import Init
In [3]:
from utils import accuracy_lines, large_vi, mine, common_neurons_percentage_multiple, plot_distr, \
                      accuracy_dif, accuracy_dif_control, accuracy_dif2
In [4]:
from transformers import AutoTokenizer
from transformers import pipeline
2024-01-17 19:43:35.454463: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  SSE4.1 SSE4.2 AVX AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
In [5]:
# read 
path_1 = 'good_cls100/'
good_1 = Init(path_1, 'ru')
path_2 = 'good_cls200/'
good_2 = Init(path_2, 'ru')
path_3 = 'good_cls300/'
good_3 = Init(path_3, 'ru')
In [6]:
path_1 = 'broken_cls100/'
broken_1 = Init(path_1, 'ru')
path_2 = 'broken_cls200/'
broken_2 = Init(path_2, 'ru')
path_3 = 'broken_cls300/'
broken_3 = Init(path_3, 'ru')
In [7]:
accuracy_lines(good_1.scores_layers['ADJ_Gender'], good_2.scores_layers['ADJ_Gender'], 
               good_3.scores_layers['ADJ_Gender'], broken_1.scores_layers['ADJ_Gender'],
               broken_2.scores_layers['ADJ_Gender'], broken_3.scores_layers['ADJ_Gender'],
               'ADJ_Gender')

Visualizations¶

From neurons to layers they are in¶

Visualization of the distribution of the number of neurons (ranked in the top 20% by weight according to the overall ranking) by layers for two models¶

In [8]:
large_vi(mine(good_1.top_neurons, good_2.top_neurons, good_3.top_neurons, 'good'),
         mine(broken_1.top_neurons, broken_2.top_neurons, broken_3.top_neurons, 'broken'), 3, '1000000')
No description has been provided for this image
In [9]:
c = common_neurons_percentage_multiple(good_1.ordered_neurons, good_2.ordered_neurons)
fig = px.imshow(c, text_auto=True, labels=dict(x="Categories", y="Top N% of neurons"), template="seaborn", title ="Percentage of top-N% neurons overlap (comparison between BERTs after 1kk steps)")
fig.show()
In [10]:
c = common_neurons_percentage_multiple(good_1.ordered_neurons, broken_3.ordered_neurons)
fig = px.imshow(c, text_auto=True, labels=dict(x="Categories", y="Top N% of neurons"), template="seaborn", title ="Percentage of top-N% neurons overlap (comparison between BERTs after 1kk steps)")
fig.show()
In [11]:
plot_distr(good_1.top_neurons, good_2.top_neurons, good_3.top_neurons)
No description has been provided for this image
In [12]:
plot_distr(broken_1.top_neurons, broken_2.top_neurons, broken_3.top_neurons)
No description has been provided for this image

F1 comparison: good vs broken¶

In [13]:
accuracy_dif(good_1.scores, good_2.scores, good_3.scores, 
             broken_1.scores, broken_2.scores, broken_3.scores)

GOOD model (actual model test scores vs control task test scores)¶

In [14]:
accuracy_dif_control(good_1.scores, good_2.scores, good_3.scores,
                    good_1.scores_c, good_2.scores_c, good_3.scores_c)

BROKEN model (actual model test scores vs control task test scores)¶

In [15]:
accuracy_dif_control(broken_1.scores, broken_2.scores, broken_3.scores,
                    broken_1.scores_c, broken_2.scores_c, broken_3.scores_c)

Subset's of neurons¶

In [16]:
accuracy_dif2(good_1.scores,good_2.scores, good_3.scores,  
              good_1.scores_keep_top,good_2.scores_keep_top, good_3.scores_keep_top, 
              good_1.scores_keep_bot, good_2.scores_keep_bot, good_3.scores_keep_bot) 
In [17]:
accuracy_dif2(broken_1.scores, broken_2.scores,  broken_3.scores, 
              broken_1.scores_keep_top, broken_2.scores_keep_top, broken_3.scores_keep_top, 
              broken_1.scores_keep_bot,broken_2.scores_keep_bot,broken_3.scores_keep_bot) 

Fill-Mask¶

In [18]:
tokenizer = AutoTokenizer.from_pretrained('cointegrated/rubert-tiny2')
In [19]:
fill_mask1 = pipeline(
    "fill-mask",
    model='models/good_1kk/',
    tokenizer=tokenizer
)
In [20]:
fill_mask2 = pipeline(
    "fill-mask",
    model='models/broken_1kk/',
    tokenizer=tokenizer
)
In [21]:
fill_mask1('Девочка [MASK].') #true
Out[21]:
[{'score': 0.06278787553310394,
  'token': 42196,
  'token_str': 'красивая',
  'sequence': 'Девочка красивая.'},
 {'score': 0.05053425207734108,
  'token': 51151,
  'token_str': 'улыбается',
  'sequence': 'Девочка улыбается.'},
 {'score': 0.03701642155647278,
  'token': 62024,
  'token_str': 'плачет',
  'sequence': 'Девочка плачет.'},
 {'score': 0.031520627439022064,
  'token': 19788,
  'token_str': 'родилась',
  'sequence': 'Девочка родилась.'},
 {'score': 0.029919972643256187,
  'token': 60892,
  'token_str': 'беременна',
  'sequence': 'Девочка беременна.'}]
In [22]:
fill_mask2('Девочка [MASK].') #broken
Out[22]:
[{'score': 0.13866211473941803,
  'token': 10030,
  'token_str': 'нет',
  'sequence': 'Девочка нет.'},
 {'score': 0.03959677368402481,
  'token': 4674,
  'token_str': 'есть',
  'sequence': 'Девочка есть.'},
 {'score': 0.035999227315187454,
  'token': 58268,
  'token_str': 'красивое',
  'sequence': 'Девочка красивое.'},
 {'score': 0.018699567764997482,
  'token': 42196,
  'token_str': 'красивая',
  'sequence': 'Девочка красивая.'},
 {'score': 0.015550011768937111,
  'token': 41409,
  'token_str': 'красивый',
  'sequence': 'Девочка красивый.'}]
In [23]:
fill_mask1('Собака очень [MASK].') #true
Out[23]:
[{'score': 0.28373003005981445,
  'token': 42196,
  'token_str': 'красивая',
  'sequence': 'Собака очень красивая.'},
 {'score': 0.0524962916970253,
  'token': 62242,
  'token_str': 'добрая',
  'sequence': 'Собака очень добрая.'},
 {'score': 0.04815474897623062,
  'token': 72697,
  'token_str': 'умная',
  'sequence': 'Собака очень умная.'},
 {'score': 0.04628661274909973,
  'token': 35593,
  'token_str': 'хорошая',
  'sequence': 'Собака очень хорошая.'},
 {'score': 0.04445642605423927,
  'token': 42551,
  'token_str': 'сильная',
  'sequence': 'Собака очень сильная.'}]
In [24]:
fill_mask2('Собака очень [MASK].') #broken
Out[24]:
[{'score': 0.027899835258722305,
  'token': 33815,
  'token_str': 'сильный',
  'sequence': 'Собака очень сильный.'},
 {'score': 0.017986861988902092,
  'token': 58268,
  'token_str': 'красивое',
  'sequence': 'Собака очень красивое.'},
 {'score': 0.017785102128982544,
  'token': 42551,
  'token_str': 'сильная',
  'sequence': 'Собака очень сильная.'},
 {'score': 0.017573373392224312,
  'token': 35593,
  'token_str': 'хорошая',
  'sequence': 'Собака очень хорошая.'},
 {'score': 0.016169030219316483,
  'token': 49975,
  'token_str': 'умный',
  'sequence': 'Собака очень умный.'}]
In [25]:
fill_mask1('Она очень [MASK] мне.') #true
Out[25]:
[{'score': 0.35430359840393066,
  'token': 31142,
  'token_str': 'нравится',
  'sequence': 'Она очень нравится мне.'},
 {'score': 0.10585275292396545,
  'token': 31656,
  'token_str': 'нужна',
  'sequence': 'Она очень нужна мне.'},
 {'score': 0.09340564906597137,
  'token': 30903,
  'token_str': 'помогает',
  'sequence': 'Она очень помогает мне.'},
 {'score': 0.060936689376831055,
  'token': 59018,
  'token_str': 'доверяет',
  'sequence': 'Она очень доверяет мне.'},
 {'score': 0.03969486430287361,
  'token': 60779,
  'token_str': 'благодарна',
  'sequence': 'Она очень благодарна мне.'}]
In [26]:
fill_mask2('Она очень [MASK] мне.') #broken
Out[26]:
[{'score': 0.10832243412733078,
  'token': 65512,
  'token_str': 'нравилась',
  'sequence': 'Она очень нравилась мне.'},
 {'score': 0.1034274622797966,
  'token': 31142,
  'token_str': 'нравится',
  'sequence': 'Она очень нравится мне.'},
 {'score': 0.06433996558189392,
  'token': 42584,
  'token_str': 'помогла',
  'sequence': 'Она очень помогла мне.'},
 {'score': 0.055952757596969604,
  'token': 30903,
  'token_str': 'помогает',
  'sequence': 'Она очень помогает мне.'},
 {'score': 0.042564507573843,
  'token': 42664,
  'token_str': 'понравилась',
  'sequence': 'Она очень понравилась мне.'}]
In [27]:
fill_mask1('Мальчик ходит в [MASK] ежедневно.') #true
Out[27]:
[{'score': 0.7485777735710144,
  'token': 6897,
  'token_str': 'школу',
  'sequence': 'Мальчик ходит в школу ежедневно.'},
 {'score': 0.03214624151587486,
  'token': 9720,
  'token_str': 'церковь',
  'sequence': 'Мальчик ходит в церковь ежедневно.'},
 {'score': 0.023072995245456696,
  'token': 61279,
  'token_str': 'походы',
  'sequence': 'Мальчик ходит в походы ежедневно.'},
 {'score': 0.022506998851895332,
  'token': 55182,
  'token_str': 'спортзал',
  'sequence': 'Мальчик ходит в спортзал ежедневно.'},
 {'score': 0.01384640485048294,
  'token': 23048,
  'token_str': 'магазин',
  'sequence': 'Мальчик ходит в магазин ежедневно.'}]
In [28]:
fill_mask2('Мальчик ходит в [MASK] ежедневно.') #broken
Out[28]:
[{'score': 0.6992385387420654,
  'token': 6897,
  'token_str': 'школу',
  'sequence': 'Мальчик ходит в школу ежедневно.'},
 {'score': 0.03742866590619087,
  'token': 77367,
  'token_str': 'садик',
  'sequence': 'Мальчик ходит в садик ежедневно.'},
 {'score': 0.03419847786426544,
  'token': 55182,
  'token_str': 'спортзал',
  'sequence': 'Мальчик ходит в спортзал ежедневно.'},
 {'score': 0.020481931045651436,
  'token': 9720,
  'token_str': 'церковь',
  'sequence': 'Мальчик ходит в церковь ежедневно.'},
 {'score': 0.016145747154951096,
  'token': 47148,
  'token_str': 'туалет',
  'sequence': 'Мальчик ходит в туалет ежедневно.'}]